package com.qianfeng.myymatou.utils;

import android.content.Context;
import android.graphics.Bitmap;
import android.util.LruCache;

import com.android.volley.NetworkResponse;
import com.android.volley.Request;
import com.android.volley.RequestQueue;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.HttpHeaderParser;
import com.android.volley.toolbox.ImageLoader;
import com.android.volley.toolbox.Volley;
import com.google.gson.Gson;

import java.io.UnsupportedEncodingException;

/**
 * Created by Administrator on 2016/7/5.
 *
 * Volley相关的自定义工具类
 * （参考铭少Week07_VolleyDemo）
 * 将Volley相关的工具类整合到一个类中
 */
public class VolleyUtils {
    private static VolleyUtils mInstance;
    private static RequestQueue mQueue;
    private MyImageCache mImgCache;
    private ImageLoader mLoader;

    //为保证单例化，1.首先将构造方法私有化
    private VolleyUtils(Context context){
        mQueue= Volley.newRequestQueue(context);
        mImgCache=new MyImageCache();
        mLoader=new ImageLoader(mQueue,mImgCache);
    }

    public RequestQueue getQueue() {
        return mQueue;
    }

    public MyImageCache getImgCache() {
        return mImgCache;
    }

    public ImageLoader getLoader() {
        return mLoader;
    }

    //2.提供一个静态方法，返回一个当前类
    public static VolleyUtils newInstance(Context context){
        if (mInstance==null){
            synchronized (VolleyUtils.class){
                if (mInstance==null){
                    mInstance=new VolleyUtils(context);
                }
            }
        }
        return mInstance;
    }

    /**
     * 自定义方法
     * @param method 请求方法：get/post
     * @param url url地址
     * @param listener 请求成功时的回调方法
     * @param errorListener 请求失败时的回调方法
     * @param clazz 要返回的Bean的类类型（字节码）
     * @param <T> 泛型，对应Bean类型
     * @return 返回gsonRequest是为了在外面能对其进行设置tag、取消请求等操作
     */
    public static <T>GsonRequest<T> newGsonRequest(int method, String url, Response.Listener<T> listener, Response.ErrorListener errorListener, Class<T> clazz){
        GsonRequest<T> gsonRequest = new GsonRequest<>(method, url, listener, errorListener, clazz);
        mQueue.add(gsonRequest);
        return gsonRequest;
    }

    /**
     * 自定义Volley中的ImageCache类
     */
    public static class MyImageCache implements ImageLoader.ImageCache {
        private LruCache<String,Bitmap> mCache;

        public MyImageCache(){
            //分配最大内存空间的1/8
            long maxMemory = Runtime.getRuntime().maxMemory() / 8;
            mCache=new LruCache<String, Bitmap>((int) maxMemory){
                @Override
                protected int sizeOf(String key, Bitmap value) {
                    //得到当前图片的大小
                    return value.getByteCount();
                }
            };
        }

        @Override
        public Bitmap getBitmap(String url) {
            return mCache.get(url);
        }

        @Override
        public void putBitmap(String url, Bitmap bitmap) {
            if (getBitmap(url)==null){
                mCache.put(url,bitmap);
            }
        }
    }

    /**
     * 自定义类（参考铭少Week07_VolleyDemo）
     * 将 访问网络获取json字符串 和 Gson解析json字符串到Bean对象 结合
     * 具体的逻辑及实现方法，参考Volley下的StringRequest类即可
     * @param <T>
     */
    public static class GsonRequest<T> extends Request<T>{
        private Response.Listener<T> mListener;
        private Class<T> mClazz;
        private Gson mGson;

        public GsonRequest(int method, String url, Response.Listener<T> listener, Response.ErrorListener errorListener, Class<T> clazz) {
            super(method, url, errorListener);
            this.mListener=listener;
            this.mClazz=clazz;
            mGson=new Gson();
        }

        @Override
        protected Response<T> parseNetworkResponse(NetworkResponse response) {
            if (response!=null){
                String parsed;
                try {
                    parsed = new String(response.data, HttpHeaderParser.parseCharset(response.headers));
                    return Response.success(mGson.fromJson(parsed,mClazz), HttpHeaderParser.parseCacheHeaders(response));
                } catch (UnsupportedEncodingException e) {
                    Response.error(new VolleyError(e));
                }

            }
            return null;
        }

        @Override
        protected void deliverResponse(T response) {
            if (mListener!=null){
                mListener.onResponse(response);
            }
        }

        @Override
        protected void onFinish() {
            super.onFinish();
            mListener=null;
        }
    }

}
